---
title: 'Quickstart: Cat Videos Example'
---

import RelationTuplePrism from '@theme/RelationTuplePrism'
RelationTuplePrism()

This example describes a video sharing service. The individual videos are
organized in directories. Every directory has an owner and every video has the
same owner as it's parent directory. The owner has elevated privileges about the
video files that are not modeled individually in Ory Keto. The only other
privilege modeled in this example is "view access." Every owner has view access
to their objects, and this privilege can be granted to other users as well. The
video sharing application interprets the special `*` user ID as any user,
including anonymous users. Note that Ory Keto does not interpret this subject
any differently from other subjects. It also does not know anything about
directory structures or induced ownership.

:::info Terminology

The "Keto client" is the application interacting with Keto. In this case we
refer to the video sharing service backend as the Keto client.

:::

## Starting the Example

First, [install Keto](./install.md).

Now you can start the example using either `docker-compose` or a bash script.
The bash script requires you to have the `keto` binary in your `$PATH`.

Alternatively, use Docker to automatically get the required images.

```shell
# clone the repository if you don't have it yet
git clone git@github.com:ory/keto.git && cd keto

docker-compose -f contrib/cat-videos-example/docker-compose.yml up
# or
./contrib/cat-videos-example/up.sh

# output: all initially created relation tuples

# NAMESPACE       OBJECT          RELATION NAME   SUBJECT
# videos          /cats/1.mp4     owner           videos:/cats#owner
# videos          /cats/1.mp4     view            videos:/cats/1.mp4#owner
# videos          /cats/1.mp4     view            *
# videos          /cats/2.mp4     owner           videos:/cats#owner
# videos          /cats/2.mp4     view            videos:/cats/2.mp4#owner
# videos          /cats           owner           cat lady
# videos          /cats           view            videos:/cats#owner
```

## State of the System

At the current state only one user with the username `cat lady` has added
videos. Both videos are in the `/cats` directory owned by `cat lady`. The file
`/cats/1.mp4` can be viewed by anyone (`*`), while `/cats/2.mp4` has no extra
sharing options, and can therefore only be viewed by its owner, `cat lady`. The
relation tuple definitions are located in the
`contrib/cat-videos-example/relation-tuples` directory.

## Simulating the Video Sharing Application

Now you can open a second terminal to run the queries against, just like the
video service client would do. In this example we will use the Keto CLI client.

If you want to run the Keto CLI within **Docker**, set the alias

```shell
alias keto="docker run -it --network cat-videos-example_default -e KETO_READ_REMOTE=\"keto:4466\" oryd/keto:v0.6.0-alpha.1"
```

in your terminal session. Alternatively, you need to set the remote endpoint so
that the Keto CLI knows where to connect to (not necessary if using Docker):

```shell
export KETO_READ_REMOTE="127.0.0.1:4466"
```

### Check Incoming Requests

First off, we get a request by an anonymous user that would like to view
`/cats/2.mp4`. The client now has to ask Keto if that operation should be
allowed or denied.

```shell
# Is "*" allowed to "view" the object "videos":"/cats/2.mp4"?
keto check "*" view videos /cats/2.mp4
# output:

# Denied
```

We already discussed that this request should be denied, but it is always good
to see this in action.

Now `cat lady` wants to change some view permissions of `/cats/1.mp4`. For this,
the video service application has to show all users that are currently allowed
to view the video. It uses Keto's
[expand-API](./concepts/api-overview.mdx#expand-subject-set) to get these data:

```shell
# Who is allowed to "view" the object "videos":"/cats/2.mp4"?
keto expand view videos /cats/1.mp4
# output:

# ∪ videos:/cats/1.mp4#view
# ├─ ∪ videos:/cats/1.mp4#owner
# │  ├─ ∪ videos:/cats#owner
# │  │  ├─ ☘ cat lady️
# ├─ ☘ *️
```

Here we can see the full subject set expansion. The first branch

```keto-relation-tuples
videos:/cats/1.mp4#view
```

indicates that every owner of the object is allowed to view

```keto-relation-tuples
videos:/cats/1.mp4#owner
```

In the next step we see that the object's owners are the owners of `/cats`

```keto-relation-tuples
videos:/cats#owner
```

Finally, we see that `cat lady` is the owner of `/cats`.

Note that there is no direct relation tuple that would grant `cat lady` view
access on `/cats/1.mp4` as this is indirectly defined via the ownership
relation.

The special user `*` on the other hand was directly granted view access on the
object, as it is a first-level leaf of the expansion tree. The following CLI
command proves that this is the case:

```shell
# Is "*" allowed to "view" the object "videos":"/cats/1.mp4"?
keto check "*" view videos /cats/1.mp4
# output:

# Allowed
```

<!--TODO-->

Updating the view permissions will be added here at a later stage.
